﻿using Microsoft.EntityFrameworkCore;
using Mojito.Data;
using Mojito.Data.Entities;
using Mojito.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Mojito.Services
{
    public class RequestService : AppServiceBase
    {
        static Dictionary<string, string> StaticVar = new Dictionary<string, string>
        {
            { "${guid}", Guid.NewGuid().ToString() },
            { "${date}", DateTime.Now.ToString("yyyy-MM-dd") }
        };

        /// <summary>
        ///  载入请求
        /// </summary>
        /// <param name="Id">请求id</param>
        /// <returns></returns>
        public async Task<Request> Get(string Id)
        {
            var reques = await Context.FindAsync<Request>(Id);
            return reques;
        }

        /// <summary>
        ///  获取请求文档
        /// </summary>
        /// <param name="requestId"></param>
        /// <returns></returns>
        public async Task<RequestExample> GetExample(string requestId)
        {
            var requestExample = await Context.RequestExample.FirstOrDefaultAsync(d => d.RequestId == requestId);
            return requestExample ?? new RequestExample() { RequestId = requestId };
        }

        /// <summary>
        ///  保存请求
        /// </summary>
        /// <param name="Id">请求id</param>
        /// <returns></returns>
        public async Task<Request> Save(RequestDto input)
        {
            var request = await Context.FindAsync<Request>(input.Id);
            if (request != null)
            {
                request.Title = input.Title;
                request.RequestUrl = input.Url;
                request.Method = input.Method;
                request.Body = input.Body;
                request.Header = input.HeaderString;
                request.Description = input.Description;
                request.Status = input.Status;
                Context.Update(request);
            }
            else
            {
                request = new Request
                {
                    Id = Guid.NewGuid().ToString("N"),
                    Title = input.Title,
                    RequestUrl = input.Url,
                    Method = input.Method,
                    Body = input.Body,
                    Header = input.HeaderString,
                    Description = input.Description,
                    Status = input.Status,
                    FolderId = input.FolderId
                };
                await Context.AddAsync(request);
            }

            var example = await Context.FindAsync<RequestExample>(input.ExampleId);   
            if(example == null)
            {
                example = new RequestExample();
                example.Id = Guid.NewGuid().ToString("N");
                example.RequestId = request.Id;
                example.Version = "1";
                if (input.RequestExample != null)
                {
                    example.RequestText = input.RequestExample.Text;
                    example.Reqeust = JsonConvert.SerializeObject(input.RequestExample.Json);
                }
                if (input.ResponseExample != null)
                {
                    example.ResponseText = input.ResponseExample.Text;
                    example.Response = JsonConvert.SerializeObject(input.ResponseExample.Json);
                }
                await Context.AddAsync(example);
            }
            else
            {
                if (input.RequestExample != null)
                {
                    example.RequestText = input.RequestExample.Text;
                    example.Reqeust = JsonConvert.SerializeObject(input.RequestExample.Json);
                }
                if (input.ResponseExample != null)
                {
                    example.ResponseText = input.ResponseExample.Text;
                    example.Response = JsonConvert.SerializeObject(input.ResponseExample.Json);
                }
                Context.Update(example);
            }
            await Context.SaveChangesAsync();
            return request;
        }

        /// <summary>
        ///  删除请求
        /// </summary>
        /// <returns></returns>
        public async Task<int> Destroy(string Id)
        {
            var exampleArray = Context.RequestExample.Where(d => d.RequestId == Id);
            Context.RemoveRange(exampleArray);

            var request = await Context.FindAsync<Request>(Id);
            if (request == null)
                throw new ApplicationException("找不到这个请求");
            Context.Remove(request);

            return await Context.SaveChangesAsync();
        }

        /// <summary>
        /// 占位符替换
        /// 系统占位符: ${}
        /// 环境占位符: {{}}
        /// </summary>
        /// <param name="source"></param>
        /// <param name="envId"></param>
        /// <returns></returns>
        public string Replace(string source, string envId)
        {
            foreach(var v in StaticVar)
                source = source.Replace(v.Key, v.Value);

            var env = Context.RequestEnviroment.Find(envId);
            if(env != null)
            {
                foreach (JProperty jToken in JObject.Parse(env.Kv).Properties())
                    source = source.Replace("{{" + jToken.Name + "}}", jToken.Value.ToString());
            }
            return source;
        }
    }
}
